home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / Mac⁄gnuucp 6.14 / source / rmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-21  |  16.9 KB  |  799 lines  |  [TEXT/KAHL]

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <errno.h>
  4. #include <pascal.h>
  5.  
  6. #define MAILCMD "rmail"
  7. #define MAXTRIES 20
  8. #include "includes.h"
  9. #include "uucp.h"
  10.  
  11. #ifdef VMS
  12. #define TERMINATOR "CTRL-Z"
  13. #define MAILSTR "MAIL %s %s"
  14. #else
  15. #define MAILSTR "/bin/mail < %s %s"
  16. #define TERMINATOR "CTRL-D"
  17. #endif
  18.  
  19. void print_out(char *, int);
  20.  
  21. void
  22. print_out (str, i)
  23. char *str;
  24. int i;
  25. {
  26.     int count;
  27.     printf("String: \n");
  28.     for (count = 0; count < i; count++)
  29.         {
  30.             putchar(str[count]);
  31.             }
  32.     putchar('\n');
  33.     }
  34.  
  35. char *rmail_version = "Mac/rmail version 6.14";
  36.  
  37. int process_queue;
  38.  
  39. int doing_alias = 0;
  40.  
  41. char curr_dir[NAMESIZE];
  42.  
  43. int
  44. rmail (argc, argv)
  45. int argc;
  46. char *argv[];
  47.  
  48. {
  49.     int i;
  50.     for (i = 1; i < argc; i++) {
  51.     if (argv[i][0] != '-')
  52.         break;
  53.     switch (argv[i][1]) {
  54.  
  55.     default:
  56.         printf("rmail: unknown flag ignored\n");
  57.  
  58.     case 'x':
  59.         debug = atoi(&argv[i][2]);
  60.         printf("rmail: debug level set to %d\n", debug);
  61.         break;
  62.     case 'q':
  63.         process_queue = true;
  64.         printf("rmail: entering server mode\n");
  65.         }
  66.     }
  67.     read_params(0);
  68.  
  69.     cuserid(who);
  70.     strcpy(host_name, "rmail");
  71.  
  72.     if (Spool == NULL) {
  73.     printf("cannot read Spool directory from Control file\n");
  74.     exit(EXIT_ERR);
  75.     }
  76.     if (Sysfile == NULL) {
  77.     printf("cannot read Sysfile directory from Control file\n");
  78.     exit(EXIT_ERR);
  79.     }
  80.     if (Myname[0] == (char)NULL) {
  81.     printf("cannot read Node name from Control file\n");
  82.     exit(EXIT_ERR);
  83.     }
  84.     /* getwd(curr_dir); */
  85.  
  86.     if (chdir(Spool) != 0) {
  87.     printf("cannot change to %s\n", Spool);
  88.     perror("can't change directory");
  89.     exit(EXIT_ERR);
  90.     }
  91.     if (process_queue)
  92.             {
  93.                 do_rmail_forever();
  94.                 return(EXIT_OK);
  95.                 }
  96.         else
  97.             return(do_rmail_interactive(argc, argv));
  98.     }
  99.     
  100.     
  101. int
  102. do_rmail_interactive(argc, argv)
  103.     int argc;
  104.     char *argv[];
  105.     {
  106.         FILE *fd;
  107.         int i;
  108.         int err;
  109.         char *argvuser = NULL;
  110.         char *argvfile = NULL;
  111.         for (i = 1; i < argc; i++) {
  112.             if (argv[i][0] == '-')
  113.             continue;
  114.  
  115.         if (argvuser == NULL) 
  116.             {
  117.                 argvuser = argv[i];
  118.                 continue;
  119.                 }
  120.         if (argvuser != NULL) 
  121.             {
  122.                 argvfile = argvuser;
  123.                 argvuser = argv[i];
  124.                 break;
  125.                 }
  126.         }
  127.  
  128.         if (argvuser == NULL) 
  129.             {
  130.                 printf("usage: rmail [-xN] [file] \"site!site!...user[@site]\"\n");
  131.                 exit(EXIT_ERR);
  132.                 }
  133.         for (i = 0; i < argc; i++)
  134.         DEBUG(2, "arg=%s\n", argv[i]);
  135.  
  136.         DEBUG(5, "user=%s\n", (argvuser == NULL ? "NULL" : argvuser));
  137.         DEBUG(5, "file=%s\n", (argvfile == NULL ? "NULL" : argvfile));
  138.         if (argvfile == NULL) 
  139.             {
  140.                 mlogit("Can't find input file for", "RMAIL");
  141.                 exit(EXIT_ERR);
  142.                 /* argvfile = "stdin";
  143.                 fd = stdin; */
  144.                 } 
  145.             else
  146.             {
  147.                 if ((fd = fopen(argvfile, "r")) == NULL) 
  148.                     {
  149.                         mlogit("CAN'T OPEN", argvfile);
  150.                         perror("can't open file for reading");
  151.                         exit(EXIT_ERR);
  152.                         }
  153.                 }
  154.         /* if (fd == stdin)
  155.             printf("\nEnter Message terminated with %s\n", TERMINATOR); */
  156.         err = do_one_rmail(argvuser, argvfile, fd);
  157.         if (fd != stdin)
  158.             {
  159.                 fclose(fd);
  160.                 FlushVol(NULL, 0);
  161.                 }
  162.         return(err);
  163.         }
  164.     
  165. char *strip_local_host (address)
  166. char *address;
  167.     {
  168.         int delim;
  169.         char tmp_address[1024];
  170.         delim = mindex(address, '!');
  171.         if ( (delim > 0) &&
  172.              ( (strncmp(address, Myname, strlen(Myname)) == 0) ||
  173.                (strncmp(address, Mynamealias, strlen(Myname)) == 0)))
  174.             {
  175.                 strcpy(tmp_address, address+delim+1);
  176.                 strcpy(address, tmp_address);
  177.                 }
  178.         delim = mindex(address, '@');
  179.         if ( (delim > 0) &&
  180.                 ( (strcmp(address+delim+1, Myname) == 0) ||
  181.                (strcmp(address+delim+1, Mynamealias) == 0) ) )
  182.            {
  183.                    address[delim] = '\0';
  184.                    }
  185.          return(address);
  186.          }
  187.    
  188. int known_host (address)
  189. char *address;
  190.     {
  191.         int delim;
  192.         char host[256];
  193.         int retval = 0;
  194.         delim = mindex(address, '!');
  195.         if (delim > 0)
  196.             {
  197.                 strncpy(host, address, delim);
  198.                 host[delim]='\0';
  199.                 retval = validate_site(host, 0);
  200.                 }
  201.         if (retval == EXIT_ERR)
  202.             {
  203.                 retval = 0;
  204.                 }
  205.         return(retval);
  206.         }
  207.  
  208. int
  209. string_contains(st1, st2)
  210. char *st1;
  211. char *st2;
  212. {
  213.     int c1;
  214.     int c2;
  215.     int len1;
  216.     int len2;
  217.     int success;
  218.     len1 = strlen(st1);
  219.     len2 = strlen(st2);
  220.     success = 1;
  221.     for (c2 = 0; c2 < len2; c2++)
  222.         {
  223.             success = 1;
  224.             for (c1 = 0; c1 < len1; c1++)
  225.                 {
  226.                     if (st1[c1] == st2[c2])
  227.                         {
  228.                             c2++;
  229.                             if (c2 > len2)
  230.                                 {
  231.                                     success = 0;
  232.                                     break;
  233.                                     }
  234.                             }
  235.                         else
  236.                         {
  237.                             success = 0;
  238.                             break;
  239.                             }
  240.                     }
  241.              if (success == 1)
  242.                  break;
  243.             }
  244.     return(success);
  245.     }
  246.                                 
  247. int
  248. do_one_rmail(argvuser, argvfile, fd)
  249. char *argvuser;
  250. char *argvfile;
  251. FILE *fd;
  252.     {
  253.         int i;
  254.         int local;
  255.         int seq;
  256.         char rmtsite[256];
  257.         char rmtuser[256];
  258.         char local_data[256];
  259.         char tmp_str[256];
  260.         char *cp, data[256], datetime[40];
  261.         char c, user[256], line[NAMESIZE];
  262.         char filebuf[256];
  263.         char recipient[256];
  264.         long nread;
  265.         unsigned long temptime;
  266.         FILE *tfd;
  267.         local = 0;
  268.         strcpy(recipient, argvuser);
  269.     /* if you can't find a "!" or an @, assume local delivery */
  270.         argvuser = strip_local_host(recipient);
  271.         if ((i = mindex(argvuser, '!')) <= 0 &&
  272.             (i = mindex(argvuser, '@')) <= 0 )
  273.             {
  274.                 argvuser = argvuser + i+1;
  275.                 strcpy(rmtsite, "tmp");    /* VMS needs this or filenames aren't legal */
  276.                 local++;
  277.                 } 
  278.             else 
  279.             {
  280.                 rmtsite[0] = '\0';
  281.                 if (!known_host(argvuser))
  282.                     {
  283.                         strcpy(rmtsite, Forwarder);
  284.                         strcpy(rmtuser, &argvuser[0]);
  285.                         }
  286.                     else
  287.                       {
  288.                           strcat(rmtsite, argvuser);
  289.                         rmtsite[i] = '\0';
  290.                         strcpy(rmtuser, &argvuser[i+1]);
  291.                         }
  292.                 if (validate_site(rmtsite, 1) != EXIT_OK)
  293.                     {
  294.                         local++;
  295.                         strcpy(rmtsite, "");
  296.                         strcpy(argvuser, postmaster);
  297.                         }
  298.                 }
  299.         sprintf(tmp_str, "D.%.30sa", rmtsite);
  300.         strcpy(tmp_str, munge_filename(tmp_str));
  301.         seq = get_seq(Spool, data);
  302.         HandleEvents();
  303.         /* sprintf(data, "D.%.7sA%04d", rmtsite, seq); */
  304.         sprintf(data, "%s%04d", tmp_str, seq);
  305.         sprintf(local_data, "%s:%s", Spool, data);
  306.         DEBUG(2, "Using data name %s\n", local_data);
  307.  
  308.         if ((tfd = fopen(local_data, "wb")) == NULL) 
  309.             {
  310.                 mlogit("CAN'T CREATE", local_data);
  311.                 fprintf(stderr, "errno = %x\n", errno);
  312.                 perror("can't open file for writing");
  313.                 exit(EXIT_ERR);
  314.                 }
  315.         time(&temptime);
  316.         sprintf(datetime, "%s%s", currtime(), Timezone);
  317.         for (cp = datetime; *cp != '\n'; cp++);
  318.         *cp = ' ';
  319.  
  320.         /* forward to rmtsite */
  321.         cuserid(user);        /* who am I ? */
  322.         HandleEvents();
  323.         for (cp = user; *cp; cp++)
  324.         if (isupper(*cp))
  325.             *cp = tolower(*cp);
  326.  
  327.         DEBUG(2, "reading %s\n", argvfile);
  328.  
  329.         /* copy data into spool file */
  330.         /* Get first line or first 255 chars */
  331.         i = 0;
  332.         while ( ((c = fgetc(fd)) != EOF) && (i < 255) && (c != '\n'))
  333.         {
  334.             HandleEvents();
  335.             tmp_str[i] = c;
  336.             i++;
  337.             }
  338.         tmp_str[i] = '\0';
  339.         /* Found one line and it begins with "From " */
  340.         if ((c == '\n') && (strncmp("From ", tmp_str, 5) == 0))
  341.             {
  342.                 char *name_end;
  343.                 char *remote_node;
  344.                 char remote_name[256];
  345.                 char user_name[256];
  346.                 char new_user_name[256];
  347.                 sscanf(tmp_str+5, "%s", user_name);
  348.                 remote_node = strstr(tmp_str, "remote from");
  349.                 if (remote_node != NULL)
  350.                     {
  351.                         remote_node = remote_node + 12;
  352.                         sscanf(remote_node, "%s", remote_name);
  353.                         if (strcmp(remote_name, Myname) == 0)
  354.                             sprintf(new_user_name, "%s", user_name);
  355.                            else
  356.                                sprintf(new_user_name, "%s!%s", remote_name, user_name);
  357.                         }
  358.                     else
  359.                     {
  360.                         strcpy(new_user_name, user_name);
  361.                         }
  362.                 fprintf(tfd, "From %s %s remote from %s\n", 
  363.                               new_user_name, datetime, Myname);
  364.                 if (doing_alias == 0)
  365.                     {
  366.                         fprintf(tfd, "Received: by %s (Mac/gnuucp v6.14) %s\n", 
  367.                                        Myname, datetime);
  368.                         }
  369.                 }
  370.             else
  371.                 {
  372.                     if (doing_alias == 0)
  373.                         {
  374.                             fprintf(tfd, "Received: by %s (Mac/gnuucp v6.14) %s\n", 
  375.                                               Myname, datetime);
  376.                             }
  377.                     fprintf(tfd, "%s", tmp_str);
  378.                     if (tmp_str[strlen(tmp_str)-1] != '\n')
  379.                         fputc('\n', tfd);
  380.                     }
  381.          while (!feof(fd))
  382.         {
  383.             nread = fread(filebuf, sizeof(char), 255L, fd);
  384.             HandleEvents();
  385.             /* printf("Read: %ld chars from %s to %s\n", 
  386.                         nread, argvfile, local_data); */
  387.             if (nread > 0)
  388.                 fwrite(filebuf, sizeof(char), nread, tfd);
  389.             if (ferror(fd))
  390.                 mlogit("Error reading file", argvfile);
  391.             if (ferror(tfd))
  392.                 mlogit("Error writing file", local_data);
  393.             }
  394.  
  395.             DEBUG(2, "%s read\n", argvfile);
  396.         if (fclose(tfd))
  397.             mlogit("Can't close:", local_data);
  398.         HandleEvents();
  399.         if (local)
  400.             {
  401.                 if (aliasp(argvuser))
  402.                     return(deliver_alias(argvuser, local_data));
  403.                   else
  404.                     return(deliver(argvuser, local_data));
  405.                     }
  406.             else
  407.                 {
  408.                     /* Send a copy to our local postmaster */
  409.                     if ( (string_contains(postmaster, rmtuser) > 0) ||
  410.                          (string_contains("Postmaster", rmtuser) > 0) ||
  411.                          (string_contains("POSTMASTER", rmtuser) > 0) ||
  412.                          (string_contains("daemon", rmtuser) > 0) ||
  413.                          (string_contains("Daemon", rmtuser) > 0) ||
  414.                          (string_contains("DAEMON", rmtuser) > 0) )
  415.                          {
  416.                              doing_alias++;
  417.                              do_rmail(postmaster, local_data, NULL_DEVICE);
  418.                              doing_alias--;
  419.                              }
  420.                     return(forward(rmtsite, rmtuser, data, user, seq));
  421.                     }
  422.             }
  423.  
  424. int
  425. aliasp (name)
  426. char *name;
  427. {
  428.     int retval;
  429.     FILE *fd;
  430.     char filename[256];
  431.     retval = 0;
  432.     if (strcmp(name, "") != 0)
  433.         {
  434.             sprintf(filename, "%s:%s", Alias, name);
  435.             if (fd = fopen(filename, "r"))
  436.             {
  437.                 retval = 1;
  438.                 fclose(fd);
  439.                 }
  440.             }
  441.     return(retval);
  442.     }
  443.  
  444. int
  445. deliver_alias (name, input)
  446. char *name;
  447. char *input;
  448. {
  449.     char filename[256];
  450.     char newname[256];
  451.     char in_line[256];
  452.     char *to_tokenize;
  453.     FILE *fd;
  454.     int    retval;
  455.     int err;
  456.     retval = EXIT_OK;
  457.     doing_alias = doing_alias + 1;
  458.     sprintf(filename, "%s:%s", Alias, name);
  459.     if (!(fd = fopen(filename, "r")))
  460.         mlogit("Mail error can't open", filename);
  461.     while (!feof(fd))
  462.     {
  463.         strcpy(in_line, "");
  464.         fgets(in_line, 255, fd);
  465.         if (in_line[strlen(in_line)-1] == '\n')
  466.             in_line[strlen(in_line)-1] = '\0';
  467.         if ((strcmp(in_line, "") != 0) && 
  468.             (in_line[0] != '#'))
  469.             {
  470.                 if (((sscanf(in_line, "%s", newname)) != 0) && 
  471.                         strcmp(newname, "") != 0)
  472.                     {
  473.                         err = do_rmail(newname, input, NULL_DEVICE);
  474.                         if (err != EXIT_OK)
  475.                             retval = err;
  476.                         }
  477.                 }
  478.             }
  479.     doing_alias = doing_alias - 1;
  480.     fclose(fd);
  481.     remove(input);
  482.     FlushVol(NULL, 0);
  483.     return(retval);
  484.     }
  485.         
  486.         
  487. int
  488. forward(rmtsite, rmtuser, dfile, user, seq)
  489. char *rmtsite, *rmtuser, *dfile, *user;
  490. int seq;
  491.  
  492. {
  493.     FILE *fbfile, *fcfile;
  494.     char tmp_str[256];
  495.     char bfile[256], cfile[256];
  496.     char umbfile[256], umcfile[256];
  497.     char umdfile[256];
  498.     char rmtdfile[256], rmtxfile[256];
  499.     char tmp[256];
  500.  
  501.     /* create a Bfile and Cfile. Dfile already exists  */
  502.     strcpy(umdfile, unmunge_filename(dfile));
  503.     sprintf(bfile, "B.%.30sa%04d", Myname, seq);
  504.     strcpy(bfile, munge_filename(bfile));
  505.     sprintf(cfile, "C.%.30sa%04d", rmtsite, seq);
  506.     strcpy(cfile, munge_filename(cfile));
  507.     sprintf(umbfile, "B.%.30sa%04d", Myname, seq);
  508.     sprintf(umcfile, "C.%.30sa%04d", rmtsite, seq);
  509.  
  510.     sprintf(rmtxfile, "X.%.7sa%04d", Myname, seq);
  511.     sprintf(rmtdfile, "D.%.7sa%04d", rmtsite, seq);
  512.  
  513.     /* The Bfile... */
  514.     sprintf(tmp_str, "%s:%s", Spool, bfile);
  515.     if ((fbfile = fopen(tmp_str, "wb")) == NULL) {
  516.     perror("cannot open bfile for writing");
  517.     return(EXIT_ERR);
  518.     }
  519.     fprintf(fbfile, "U %s %s\n", user, Myname);
  520.     fprintf(fbfile, "F %s\n", rmtdfile);
  521.     fprintf(fbfile, "I %s\n", rmtdfile);
  522.  
  523.     fprintf(fbfile, "C %s %s\n", MAILCMD, rmtuser);
  524.  
  525.     if (fclose(fbfile) == EOF) {
  526.     printf("cannot close cfile\n");
  527.     return(EXIT_ERR);
  528.     }
  529.     /* The Cfile... */
  530.  
  531.     sprintf(tmp_str, "%s:%s", Spool, cfile);
  532.        if ((fcfile = fopen(tmp_str, "wb")) == NULL) {
  533.     perror("cannot open cfile for writing");
  534.     return(EXIT_ERR);
  535.     }
  536.     fprintf(fcfile, "S %s %s %s - %s 0666\n", umdfile, rmtdfile, user, umdfile);
  537.     fprintf(fcfile, "S %s %s %s - %s 0666\n", umbfile, rmtxfile, user, umbfile);
  538.  
  539.     if (fclose(fcfile) == EOF) {
  540.     perror("cannot close fcfile\n");
  541.     return(EXIT_ERR);
  542.     }
  543.     sprintf(tmp, "C %s %s", MAILCMD, rmtuser);
  544.     mlogit("XQT QU'ED", tmp);
  545.     return(EXIT_OK);
  546. }
  547.  
  548. int
  549. validate_site(name, errp)
  550. char *name;
  551. int errp;
  552.  
  553. {
  554.     char tmp[NAMESIZE];
  555.     FILE *fd;
  556.     int found = 0;
  557.  
  558.     if ((fd = fopen(Sysfile, "r")) == NULL) {
  559.     printf("cannot open %s\n", Sysfile);
  560.     mlogit("FAIL", "can't read Sysfile");
  561.     exit(EXIT_ERR);
  562.     }
  563.     while (fgets(tmp, sizeof(tmp), fd) != NULL)
  564.     if (strncmp(tmp, name, strlen(name)) == 0) {
  565.         found = 1;
  566.         break;
  567.     }
  568.     if (fclose(fd)) {
  569.     printf("can't close %s\n", Sysfile);
  570.     }
  571.     if (!found) 
  572.         {
  573.             if (errp)
  574.                 {
  575.                     printf("%s -- unknown site\n", name);
  576.                     mlogit("FAIL", "bad site");
  577.                     }
  578.             return(EXIT_ERR);
  579.             }
  580.     /* exit(EXIT_ERR);*/
  581.     return(EXIT_OK);
  582. }
  583.  
  584.  /* Deliver file using local mailer If mail fails, send to it to postmaster.
  585.   * If that fails, give up and die */
  586.  
  587. int
  588. deliver(addressee, data)
  589. char *addressee;
  590. char *data;
  591.  
  592. {
  593.     int mail_err;
  594.     char line[NAMESIZE];
  595.     char tmp_str[256];
  596.       /* Invoke the mailer */
  597.     if (  ((mail_err = mail("mail", addressee, data)) != EXIT_OK) &&
  598.           (strcmp(postmaster, addressee) == 0) )
  599.           {
  600.             sprintf(line, "%s %s %s", "mail", addressee, data);
  601.             mlogit("FAILED", line);
  602.             doing_alias++;
  603.             if (do_rmail(postmaster, data, NULL_DEVICE) != EXIT_OK)
  604.                 /* mail("mail", postmaster, data) != EXIT_OK) */
  605.                 {
  606.                     doing_alias--;
  607.                     sprintf(line, "%s %s %s", "mail", postmaster, data);
  608.                     mlogit("FAILED", line);
  609.                     exit(EXIT_ERR);
  610.                     }
  611.                 else
  612.                     doing_alias--;
  613.             }
  614.     sprintf(line, "%s %s %s", "mail", addressee, data);
  615.     mlogit("OK", line);
  616.     if (remove(data) == 0)
  617.             mlogit("DELETED", data);
  618.         else
  619.             {
  620.                 mlogit("CAN'T DELETE", data);
  621.                 printf("\nErrno: %d\n", errno);
  622.                 }
  623.     return(mail_err);
  624. }
  625.  
  626. #define MAXOPENS 5
  627.  
  628. int
  629. mail (command, addressee, input)
  630. char *command, *addressee, *input;
  631.  
  632. {
  633.     char line[256];
  634.     char tmp_out[256];
  635.     FILE *out;
  636.     FILE *in;
  637.     int c;
  638.     int i;
  639.     int status;
  640.     long nread;
  641.     char filebuf[256];
  642.     sprintf(tmp_out, "%s:%s", Mail, addressee);
  643.     for (i = 0; i< MAXOPENS; i++)
  644.         {
  645.             /* Some one else may have the mail file open */
  646.             DEBUG(4, "Trying to open: %s\n", tmp_out);
  647.             if ((out = fopen(tmp_out, "a")) != NULL)
  648.             {
  649.                 break;
  650.                 }
  651.             gnusleep(1);
  652.         }
  653.     if (out == NULL)
  654.         {
  655.             DEBUG(0, "Couldn't open: %s\n", tmp_out);
  656.             return(EXIT_ERR);
  657.             }
  658.     if ((in = fopen(input, "r")) == NULL)
  659.         {
  660.             DEBUG(4, "Couldn't open: %s\n", input);
  661.             fclose(out);
  662.             return(EXIT_ERR);
  663.             }
  664.     /* while ((c = fgetc(in)) != EOF)
  665.         {
  666.             HandleEvents();
  667.             fputc(c, out);
  668.             } */
  669.     while (!feof(in))
  670.         {
  671.             nread = fread(filebuf, sizeof(char), 255, in);
  672.             HandleEvents();
  673.             if (nread > 0)
  674.                 fwrite(filebuf, sizeof(char), nread, out);
  675.             if (ferror(in))
  676.                 mlogit("Error reading file", input);
  677.             if (ferror(out))
  678.                 mlogit("Error reading file", tmp_out);
  679.             }
  680.  
  681.        fputc(255, out);
  682.     fputc('\r', out);
  683.     fclose(in);
  684.     fclose(out);
  685.     return(EXIT_OK);
  686. }
  687.  
  688. int
  689. get_seq(dir, partial)
  690. char *dir;
  691. char *partial;
  692. {
  693.     /* pick a random num and make a unique file name from it /* FIXME: How do
  694.      * real systems do this? What about ensuring uniqueness at the remote
  695.      * site? */
  696.  
  697.     int i;
  698.     int seq;
  699.     char file[256];
  700.  
  701.     for (i = 0; i <= MAXTRIES; i++) {
  702.     seq = (rand()*9999.0)/RAND_MAX;
  703.     sprintf(file, "%s:%s%04d", dir, partial, seq);
  704.     if (access(file, 0) != 0)    /* doesn't already exist */
  705.         return seq;
  706.     }
  707.     if (i == MAXTRIES) {
  708.         printf("can't generate unique file name\n");
  709.         exit(EXIT_ERR);
  710.     }
  711. }
  712.  
  713. int
  714. do_rmail_forever ()
  715.     {
  716.         long i;
  717.         EventRecord event;
  718.         while (true)
  719.             {
  720.                 do_rmail_queue();
  721.                 gnusleep(10);
  722.                 }
  723.                 
  724.         }
  725.  
  726. int
  727. do_rmail_queue ()
  728. {
  729.     char *work;
  730.     FILE *fd;
  731.     int len;
  732.     char work_str[256];
  733.     char user[256];
  734.     char file[256];
  735.     while (work_scan(NULL, "RMAIL"))
  736.         {
  737.             HandleEvents();
  738.             work = work_next();
  739.             sprintf(work_str,"%s:%s", Spool, work);
  740.             fd = fopen(work_str, "r");
  741.             if (fd == NULL)
  742.                 {
  743.                     mlogit("Couldn't open RMAIL work file", work_str);
  744.                     return(1);
  745.                     }
  746.             /* fscanf(fd, "%s%s", user, file); */
  747.             fgets(file, 255, fd);
  748.             len = strlen(file);
  749.             if (file[len-1] = '\n')
  750.                 {
  751.                     file[len-1] = '\0';
  752.                     }
  753.             fgets(user, 255, fd);
  754.             len = strlen(user);
  755.             if (user[len-1] = '\n')
  756.                 {
  757.                     user[len-1] = '\0';
  758.                     }
  759.             fclose(fd);
  760.             fd = fopen(file, "r");
  761.             if (fd == NULL)
  762.                 {
  763.                     mlogit("Couldn't open RMAIL input file", file);
  764.                     return(EXIT_ERR);
  765.                     }
  766.             if (do_one_rmail(user, file, fd) == EXIT_OK)
  767.                 {
  768.                     fclose(fd);
  769.                     remove(work_str);
  770.                     remove(file);
  771.                     }
  772.                 else
  773.                     {
  774.                         fclose(fd);
  775.                         mlogit("Couldn't send mail for work file", work_str);
  776.                         return(EXIT_ERR);
  777.                         }
  778.             
  779.             }
  780.         return(0);
  781.     }
  782.     
  783.  
  784. int
  785. do_rmail (addressee, input, output)
  786. char *addressee;
  787. char *input;
  788. char *output;
  789.     {
  790.         int argc;
  791.         char *argv[5];
  792.         argc = 3;
  793.         argv[0] = "";
  794.         argv[2] = addressee;
  795.         argv[1] = input;
  796.         /* argv[2] = output; */
  797.         return(rmail(argc, argv));
  798.         }
  799.